package io.renren.modules.com.service.impl;

import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.NumberUtil;

import io.renren.modules.com.dao.ComAItemDao;
import io.renren.modules.com.entity.ComAItemEntity;
import io.renren.modules.com.entity.ComCrChargingitemEntity;
import io.renren.modules.com.service.ComAItemService;

@Service("comAItemService")
public class ComAItemServiceImpl implements ComAItemService {

	@Autowired
	private ComAItemDao comAItemDao;

	@Override
	public ComAItemEntity queryObject(Long serialNo) {
		return comAItemDao.queryObject(serialNo);
	}

	@Override
	public List<ComAItemEntity> queryList(Map<String, Object> map) {
		return comAItemDao.queryList(map);
	}

	@Override
	public int queryTotal(Map<String, Object> map) {
		return comAItemDao.queryTotal(map);
	}

	@Override
	public void save(ComCrChargingitemEntity comCrChargingitem, Long aSerialNo, String collectionDays) {
		savePrivate(comCrChargingitem, aSerialNo, collectionDays);
	}

	@Transactional
	private void savePrivate(ComCrChargingitemEntity comCrChargingitem, Long aSerialNo, String collectionDays) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		SimpleDateFormat sdfha = new SimpleDateFormat("yyyy-MM-dd");
		// 收款日期
		Date wyj = DateUtil.parse(collectionDays);
		// 计费开始日期
		Date qyd = DateUtil.parse(comCrChargingitem.getChargingSd());
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(qyd);
		// 计费结束日期
		Date pfp = DateUtil.parse(comCrChargingitem.getChargingEd());
		List<ComAItemEntity> comAItemList = new ArrayList<ComAItemEntity>();
		// 收款日期＞计费周期截止日期，则收款金额全部分摊到收款当月
		if (wyj.after(pfp)) {
			for (int i = 0; i < comCrChargingitem.getMonth(); i++) {
				ComAItemEntity comAItem = new ComAItemEntity();
				comAItem.setCrSerialNo(aSerialNo);
				comAItem.setItem(comCrChargingitem.getChargingItem());
				comAItem.setYearMonth(sdf.format(calendar.getTime()));
				comAItem.setJapan(0.0);
				comAItemList.add(comAItem);
				calendar.add(Calendar.MONTH, 1);
			}
			if (StringUtils.equals(sdf.format(wyj), comAItemList.get(comAItemList.size() - 1).getYearMonth())) {
				comAItemList.get(comAItemList.size() - 1).setJapan(comCrChargingitem.getPayAmount());
			} else {
				ComAItemEntity comAItem = new ComAItemEntity();
				comAItem.setCrSerialNo(aSerialNo);
				comAItem.setItem(comCrChargingitem.getChargingItem());
				comAItem.setYearMonth(sdf.format(wyj));
				comAItem.setJapan(comCrChargingitem.getPayAmount());
				comAItemList.add(comAItem);
			}
		}
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(2);
		nf.setRoundingMode(RoundingMode.UP);
		nf.setGroupingUsed(false);
		Double japan = Double
				.parseDouble(nf.format(NumberUtil.div(comCrChargingitem.getPayAmount(), comCrChargingitem.getMonth())));
		Double duck = 0.0;
		// 如果收款日期＜计费周期起始日期，则收款金额平均分摊到计费周期
		if (wyj.before(qyd)) {
			for (int i = 0; i < comCrChargingitem.getMonth(); i++) {
				ComAItemEntity comAItem = new ComAItemEntity();
				comAItem.setCrSerialNo(aSerialNo);
				comAItem.setItem(comCrChargingitem.getChargingItem());
				comAItem.setYearMonth(sdf.format(calendar.getTime()));
				if (i != comCrChargingitem.getMonth() - 1) {
					comAItem.setJapan(japan);
					duck += japan;
				} else {
					comAItem.setJapan(NumberUtil.sub(comCrChargingitem.getPayAmount(), duck));
				}
				comAItemList.add(comAItem);
				calendar.add(Calendar.MONTH, 1);
			}
		}
		// 计费周期起始日<=收款日期<=计费周期截止日期，则收款当月分摊金额=收款金额/月份数*（收费当月-计费起始月份+1），剩余月份分摊金额=（收款金额-收款当月分摊金额）/剩余月份
		if ((wyj.after(qyd) || StringUtils.equals(sdfha.format(wyj), sdfha.format(qyd)))
				&& (wyj.before(pfp) || StringUtils.equals(sdfha.format(wyj), sdfha.format(pfp)))) {
			Calendar razor = Calendar.getInstance();
			razor.setTime(pfp);
			int villkiss = razor.get(Calendar.MONTH) - calendar.get(Calendar.MONTH);
			if (StringUtils.equals(sdf.format(wyj), sdf.format(pfp)) && villkiss == comCrChargingitem.getMonth()) {
				calendar.add(Calendar.MONTH, 1);
			}
			for (int i = 0; i < comCrChargingitem.getMonth(); i++) {
				ComAItemEntity comAItem = new ComAItemEntity();
				comAItem.setCrSerialNo(aSerialNo);
				comAItem.setItem(comCrChargingitem.getChargingItem());
				comAItem.setYearMonth(sdf.format(calendar.getTime()));
				if (comCrChargingitem.getMonth() == 1) {
					comAItem.setJapan(comCrChargingitem.getPayAmount());
				} else {
					if (i == comCrChargingitem.getMonth() - 1) {
						comAItem.setJapan(NumberUtil.sub(comCrChargingitem.getPayAmount(), duck));
					} else {
						if (StringUtils.equals(sdf.format(wyj), sdf.format(calendar.getTime()))) {
							comAItem.setJapan(NumberUtil.mul(japan, i + 1));
							duck += NumberUtil.mul(japan, i + 1);
						} else {
							if (calendar.getTime().before(wyj)) {
								comAItem.setJapan(0.0);
							}
							if (calendar.getTime().after(wyj)) {
								comAItem.setJapan(japan);
								duck += japan;
							}
						}
					}
				}
				comAItemList.add(comAItem);
				calendar.add(Calendar.MONTH, 1);
			}
		}
		for (ComAItemEntity comAItemEntity : comAItemList) {
			comAItemDao.save(comAItemEntity);
		}
	}

	@Override
	public void update(List<List<Object>> apportionList, Long crSerialNo) {
		updatePrivate(apportionList, crSerialNo);
	}

	@Transactional
	private void updatePrivate(List<List<Object>> apportionList, Long crSerialNo) {
		ComAItemEntity comAItem = new ComAItemEntity();
		for (List<Object> list : apportionList) {
			comAItem.setCrSerialNo(crSerialNo);
			comAItem.setYearMonth(list.get(0).toString());
			if (null != list.get(1) && StringUtils.isNotBlank(list.get(1).toString())) {
				comAItem.setItem("租金");
				comAItem.setJapan(Double.valueOf((String) list.get(1)));
				comAItemDao.save(comAItem);
			}
			if (null != list.get(2) && StringUtils.isNotBlank(list.get(2).toString())) {
				comAItem.setItem("物业费");
				comAItem.setJapan(Double.valueOf((String) list.get(2)));
				comAItemDao.save(comAItem);
			}
			if (null != list.get(3) && StringUtils.isNotBlank(list.get(3).toString())) {
				comAItem.setItem("管理费");
				comAItem.setJapan(Double.valueOf((String) list.get(3)));
				comAItemDao.save(comAItem);
			}
			if (null != list.get(4) && StringUtils.isNotBlank(list.get(4).toString())) {
				comAItem.setItem("公共能耗费");
				comAItem.setJapan(Double.valueOf((String) list.get(4)));
				comAItemDao.save(comAItem);
			}
			if (null != list.get(5) && StringUtils.isNotBlank(list.get(5).toString())) {
				comAItem.setItem("停车费");
				comAItem.setJapan(Double.valueOf((String) list.get(5)));
				comAItemDao.save(comAItem);
			}
			if (null != list.get(6) && StringUtils.isNotBlank(list.get(6).toString())) {
				comAItem.setItem("其他");
				comAItem.setJapan(Double.valueOf((String) list.get(6)));
				comAItemDao.save(comAItem);
			}
			if (null != list.get(7) && StringUtils.isNotBlank(list.get(7).toString())) {
				comAItem.setItem("租场费");
				comAItem.setJapan(Double.valueOf((String) list.get(7)));
				comAItemDao.save(comAItem);
			}
		}
	}

	@Override
	public void delete(Long serialNo) {
		comAItemDao.delete(serialNo);
	}

	public void deleteByCrSerialNo(Long crSerialNo) {
		comAItemDao.deleteByCrSerialNo(crSerialNo);
	}

	public void deleteEVA(Long crSerialNo) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		comAItemDao.deleteEVA(crSerialNo, sdf.format(new Date()));
	}

	@Override
	public void deleteBatch(Long[] serialNos) {
		comAItemDao.deleteBatch(serialNos);
	}

	public void deleteBatchByCrSerialNos(Long[] crSerialNos) {
		comAItemDao.deleteBatchByCrSerialNos(crSerialNos);
	}

	public int querya(Map<String, Object> map) {
		return comAItemDao.querya(map);
	}

	public int queryb(Map<String, Object> map) {
		return comAItemDao.queryb(map);
	}

	public Double queryd(Map<String, Object> map) {
		return comAItemDao.queryd(map);
	}

	public Double querye(Map<String, Object> map) {
		return comAItemDao.querye(map);
	}

	public Double queryg(Map<String, Object> map) {
		return comAItemDao.queryg(map);
	}

	public List<List<Object>> historicalRecords(Long crSerialNo) {
		return historicalRecordsPrivate(crSerialNo);
	}

	private List<List<Object>> historicalRecordsPrivate(Long crSerialNo) {
		List<List<Object>> apportionList = new ArrayList<List<Object>>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		String minYearMonth = comAItemDao.minYearMonth(crSerialNo);
		Date minDate = DateUtil.parse(minYearMonth, sdf);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(minDate);
		String maxYearMonth = comAItemDao.maxYearMonth(crSerialNo);
		Date maxDate = DateUtil.parse(maxYearMonth, sdf);
		Date nowDate = new Date();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("crSerialNo", crSerialNo);
		List<ComAItemEntity> comAItemList = null;
		while (calendar.getTime().before(maxDate) || StringUtils.equals(sdf.format(calendar.getTime()), maxYearMonth)) {
			map.put("yearMonth", sdf.format(calendar.getTime()));
			List<Object> list = initializeArrayList();
			if (calendar.getTime().before(nowDate)
					&& !StringUtils.equals(sdf.format(calendar.getTime()), sdf.format(nowDate))) {
				list.set(0, "before");
			} else {
				list.set(0, "after");
			}
			list.set(1, sdf.format(calendar.getTime()));
			comAItemList = comAItemDao.findMore(map);
			if (CollectionUtil.isNotEmpty(comAItemList)) {
				for (ComAItemEntity comAItem : comAItemList) {
					if (StringUtils.equals("租金", comAItem.getItem())) {
						list.set(2, comAItem.getJapan());
					}
					if (StringUtils.equals("物业费", comAItem.getItem())) {
						list.set(3, comAItem.getJapan());
					}
					if (StringUtils.equals("管理费", comAItem.getItem())) {
						list.set(4, comAItem.getJapan());
					}
					if (StringUtils.equals("公共能耗费", comAItem.getItem())) {
						list.set(5, comAItem.getJapan());
					}
					if (StringUtils.equals("停车费", comAItem.getItem())) {
						list.set(6, comAItem.getJapan());
					}
					if (StringUtils.equals("租场费", comAItem.getItem())) {
						list.set(8, comAItem.getJapan());
					}
					if (StringUtils.equals("其他", comAItem.getItem())) {
						list.set(7, comAItem.getJapan());
					}
				}
			}
			apportionList.add(list);
			calendar.add(Calendar.MONTH, 1);
		}
		if (nowDate.after(maxDate) && !StringUtils.equals(sdf.format(nowDate), maxYearMonth)) {
			List<Object> list = initializeArrayList();
			list.set(0, "after");
			list.set(1, sdf.format(nowDate));
			apportionList.add(list);
		}
		return apportionList;
	}

	/**
	 * 初始化长度为10，值全为空的ArrayList
	 * 
	 * @return
	 */
	public List<Object> initializeArrayList() {
		List<Object> list = new ArrayList<Object>();
		list.add("");
		list.add("");
		list.add("");
		list.add("");
		list.add("");
		list.add("");
		list.add("");
		list.add("");
		list.add("");
		return list;
	}

	public ComAItemEntity minMax(Long crSerialNo, String item) {
		return comAItemDao.minMax(crSerialNo, item);
	}

}
